package com.blockmeta.bbs.businesslibrary.widget.chartview.Tools;


import com.blockmeta.bbs.businesslibrary.widget.chartview.CandleData;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

/**
 * Created by ting on 17/2/8.
 */

public class KDJIndicator
{
	private double RSV = 50.0;

	private double lastK = 50.0;
	private double lastD = 50.0;

	private double minPrice = Double.MAX_VALUE;
	private double maxPrice = 0.0;


	public List<KdjData> computeKDJ(List<CandleData> historyPrices, int n, int m1, int m2)
	{

		Deque<Double> nineDayMin = new ArrayDeque<>(n);
		Deque<Double> nineDayMax = new ArrayDeque<>(n);

		List<KdjData> kdjs = new ArrayList<>();

		if (historyPrices == null || historyPrices.size() == 0)
		{
			return kdjs;
		}


		boolean first = true;

		int size = historyPrices.size();

		for (int i = 0; i < size; i++)
		{
			CandleData hPrice = historyPrices.get(i);

			double price = hPrice.getDbClose();
			double min = hPrice.getDbLow();
			double max = hPrice.getDbHigh();

			nineDayMax.add(max);
			nineDayMin.add(min);

			if (nineDayMin.size() > n)
			{
				double removeMax = nineDayMax.removeFirst().doubleValue();

				if (removeMax == maxPrice)
				{
					if (max >= removeMax)
					{
						maxPrice = max;
					}
					else
					{
						// 遍历一次
						maxPrice = 0.0;
						for (Double nine : nineDayMax)
						{
							if (nine > maxPrice)
							{
								maxPrice = nine;
							}
						}
					}
				}
				else
				{
					if (max > maxPrice)
					{
						maxPrice = max;
					}
				}

				double removeMin = nineDayMin.removeFirst().doubleValue();
				if (removeMin == minPrice)
				{
					if (min <= removeMin)
					{
						minPrice = min;
					}
					else
					{
						// 遍历一次
						minPrice = Double.MAX_VALUE;
						for (Double nine : nineDayMin)
						{
							if (nine < minPrice)
							{
								minPrice = nine;
							}
						}
					}
				}
				else
				{
					if (min < minPrice)
					{
						minPrice = min;
					}
				}
			}
			else
			{
				if (max > maxPrice)
				{
					maxPrice = max;
				}
				if (min < minPrice)
				{
					minPrice = min;
				}
			}

			KdjData kdj = new KdjData();

			if (i == 0 || maxPrice == minPrice)
			{
				RSV = 50.0;
			}
			else
			{
				RSV = (price - minPrice) * 100 / (maxPrice - minPrice);
			}
//			Double k = 2 * lastK / 3 + 1 * RSV / 3;

			Double k = (m1 - 1) * lastK / m1 + 1 * RSV / m1;

//			Double d = 2 * lastD / 3 + 1 * k / 3;

			Double d = (m2 - 1) * lastD / m2 + 1 * k / m2;
			Double j = 3 * k - 2 * d;

			lastK = k;
			lastD = d;

			kdj.setLastK(lastK);
			kdj.setLastD(lastD);

			kdj.setK(k);
			kdj.setD(d);
			if (j < 100 && j > 0)
			{
				kdj.setJ(j);
			}
			else if (j > 100)
			{
				kdj.setJ(100.0);
			}
			else if (j < 0)
			{
				kdj.setJ(0.0);
			}

			kdjs.add(kdj);
		}
		return kdjs;
	}
}
